package adapter

import (
	"github.com/hyperway/pkg/component"
	"github.com/hyperway/pkg/constant"
	"github.com/hyperway/pkg/helper"
	"github.com/hyperway/pkg/logger"
	"github.com/labstack/echo/v4"
	"net/http"
)

// defaultErrorHandler is the default error handler.
func defaultErrorHandler(ctx component.WebContext, err error) {
	serverError, ok := err.(*component.ServerError)
	if !ok {
		serverError = &component.ServerError{
			StatusCode: http.StatusInternalServerError,
			ErrorCode:  "500",
			Message:    err.Error(),
		}
	}
	if bytes, e := toBytes(serverError); e != nil {
		logger.TraceId(ctx.RequestId()).Errorw("failed to serialize response data to json", "error", e)
		return
	} else {
		ctx.Write(serverError.StatusCode, "application/json;charset=UTF-8", bytes)
	}
}

// defaultNotFoundHandler is the default not found handler.
func defaultNotFoundHandler(ctx component.WebContext) error {
	return ctx.WriteJSON(http.StatusNotFound, "Not Found")
}

// ToWebContext returns the WebContext from echo.Context.
func ToWebContext(c echo.Context) component.WebContext {
	ctx, ok := c.Get(constant.RequestScopeContextKey).(component.WebContext)
	helper.IsFalsePanic(ok == true && ctx != nil, "<web-context> not found in echo.context")
	return ctx
}

type (
	// RequestFilterAdapt 实现 component.RequestFilter 与Echo框架的echo.MiddlewareFunc函数适配，用于在路由后执行
	RequestFilterAdapt component.RequestFilterFunc
	// PreRequestFilterFuncAdapt 实现 component.PreRequestFilterFunc 与Echo框架的echo.MiddlewareFunc函数适配，用于在路由前执行
	PreRequestFilterFuncAdapt component.PreRequestFilterFunc
)

// AdaptPreRequestFilterFunc 实现 component.RequestFilter 与Echo框架的echo.MiddlewareFunc函数适配，用于在路由前执行
func (f PreRequestFilterFuncAdapt) AdaptPreRequestFilterFunc(handlerFunc echo.HandlerFunc) echo.HandlerFunc {
	return func(c echo.Context) error {
		return f(func(webex component.WebContext) error {
			return handlerFunc(c)
		})(ToWebContext(c))
	}
}

// AdaptRequestFilterFunc 实现 component.RequestFilter 与Echo框架的echo.MiddlewareFunc函数适配，用于在路由后执行
func (f RequestFilterAdapt) AdaptRequestFilterFunc(handlerFunc echo.HandlerFunc) echo.HandlerFunc {
	return func(c echo.Context) error {
		return f(func(webex component.WebContext) error {
			return handlerFunc(c)
		})(ToWebContext(c))
	}
}
